package com.anjie.powerproject.config;

import com.anjie.powerproject.common.Constants;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用来存储临时数据的Map，单例
 */
@Component
public class DataCache {
    private volatile ConcurrentHashMap<String, DataObject> dataCacheMap;

    private volatile ConcurrentHashMap<Integer, ExecuteResult> executeResultMap;

    private ConcurrentHashMap<String, DataObject> getDataCacheMap() {
        if (dataCacheMap == null) {
            synchronized (DataCache.class) {
                if (dataCacheMap == null) {
                    dataCacheMap = new ConcurrentHashMap<>(16);
                }
            }
        }
        return dataCacheMap;
    }

    public ConcurrentHashMap<Integer, ExecuteResult> getExecuteResultMap() {
        if (executeResultMap == null) {
            synchronized (DataCache.class) {
                if (executeResultMap == null) {
                    executeResultMap = new ConcurrentHashMap<>(16);
                }
            }
        }
        return executeResultMap;
    }

    public void save(String key, DataObject val) {
        ConcurrentHashMap<String, DataObject> dataCacheMap = getDataCacheMap();
        dataCacheMap.put(key, val);
    }

    public void saveExecuteResult(Integer modelId, Boolean complete) {
        ConcurrentHashMap<Integer, ExecuteResult> executeResultMap = getExecuteResultMap();
        executeResultMap.put(modelId, new ExecuteResult(complete));
    }

    public void saveExecuteResult(Integer modelId, ExecuteResult executeResult) {
        ConcurrentHashMap<Integer, ExecuteResult> executeResultMap = getExecuteResultMap();
        executeResultMap.put(modelId, executeResult);
    }

    public void removeExecuteResult(Integer modelId) {
        ConcurrentHashMap<Integer, ExecuteResult> executeResultMap = getExecuteResultMap();
        executeResultMap.remove(modelId);
    }

    public DataObject load(String key) {
        ConcurrentHashMap<String, DataObject> dataCacheMap = getDataCacheMap();
        return dataCacheMap.get(key);
    }

    public ExecuteResult loadExecuteResult(Integer modelId) {
        ConcurrentHashMap<Integer, ExecuteResult> executeResultMap = getExecuteResultMap();
        return executeResultMap.get(modelId);
    }

    /**
     * 定期删除内存中超时时间太长的对象(每隔一个小时执行一次)
     */
    @Scheduled(cron = "0 0 0/1 * * ?")
    public void expire() {
        Map<String, DataObject> dataCacheMap = getDataCacheMap();
        if (dataCacheMap == null) {
            return;
        }
        for (Map.Entry<String, DataObject> entry : dataCacheMap.entrySet()) {
            DataObject dataObject = entry.getValue();
            Date timestamp = dataObject.getTimestamp();
            if (timestamp == null || new Date().getTime() - timestamp.getTime() > Constants.EXPIRE_SPAN) {
                dataCacheMap.remove(entry.getKey());
            }
        }
    }

    @Scheduled(cron = "0 0 0 0/1 * ?")
    public void expire2() {
        ConcurrentHashMap<Integer, ExecuteResult> executeResultMap = getExecuteResultMap();
        if (executeResultMap == null) {
            return;
        }
        for (Map.Entry<Integer, ExecuteResult> entry : executeResultMap.entrySet()) {
            DataObject dataObject = entry.getValue();
            Date timestamp = dataObject.getTimestamp();
            if (timestamp == null || new Date().getTime() - timestamp.getTime() > Constants.EXPIRE_SPAN) {
                executeResultMap.remove(entry.getKey());
            }
        }
    }
}
